﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace RoketSolutions.SP2010.Infrostructure.UI.Ajax.Controllers
{
    public class Cache<TKey, TValue> where TValue : class
    {
        private readonly Dictionary<TKey, TValue> cache;
        private readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();

        public Cache()
        {
            cache = new Dictionary<TKey, TValue>();
        }

        public TValue GetEntry(TKey key, Func<TValue> creator)
        {
            rwlock.EnterReadLock();
            try
            {
                TValue entry;
                if (cache.TryGetValue(key, out entry))
                    return entry;
            }
            finally
            {
                rwlock.ExitReadLock();
            }

            if(creator != null)
            {
                var entry = creator();
                rwlock.EnterWriteLock();
                try
                {
                    TValue existingEntry;
                    if (cache.TryGetValue(key, out existingEntry))
                        return existingEntry;
                    cache[key] = entry;
                    return entry;
                }
                finally
                {
                    rwlock.ExitWriteLock();
                }
            }
            return null;
        }
    }
}
